package com.aorise.shiro;

import com.aorise.model.system.Role;
import com.aorise.model.system.User;
import com.aorise.service.system.UserService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * @Auther: zhouhao
 * @Date: 2019/4/26
 * @Description:
 */
public class PermissionRealm extends AuthorizingRealm{

    @Autowired
    @Lazy
    UserService userService;

    /**
     * 授权
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        User user = (User) SecurityUtils.getSubject().getPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        List<Role> roles = user.getRoles();
        if(CollectionUtils.isNotEmpty(roles)){
            roles.stream().forEach(role -> {
                info.addRole(role.getRoleName());
                role.getAuthorities().stream().forEach(authority -> {
                    info.addStringPermission(authority.getPermission());
                });
            });
        }
        return info;
    }

    /**
     * 认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String account = (String) token.getPrincipal(); // 获取用户登录账号
        /**截取用户账号与用户类型 */
        String[] accounts=account.split("#");
        account=accounts[0];
        Integer userType=Integer.valueOf(accounts[1]);
        List<User> users = userService.selectByAccount(account,userType);
        if(CollectionUtils.isEmpty(users)){
            throw new AccountException("输入的账号密码有误，请重新输入");
        }
        token.setRememberMe(false);
        return new SimpleAuthenticationInfo(users.get(0), users.get(0).getPassword(),getName());
    }

    /**
     * 设定Password校验.
     */
    @PostConstruct
    public void initCredentialsMatcher() {
        //该句作用是重写shiro的密码验证，让shiro用我自己的验证
        setCredentialsMatcher(new CustomCredentialsMatcher());
    }
}
